package logic

import (
	"core/command"
	"core/common"
	"core/component/logger"
	"core/network"
	"encoding/json"
	"runtime/debug"
)

type Client struct {
	*network.NetConn
	robotID      uint64 //机器人id
	remoteAddr   string
	joinOnlineID string
	bindOnline   bool
	//msgRegOnce   sync.Once // 代理消息注册一次
	handlers map[command.Command]command.MsgHandler
	z        int
	lastTime int64
}

func (cli *Client) Init() {
	cli.handlers = make(map[command.Command]command.MsgHandler)
	cli.registerGatewayOnlineHandler()
}

// gatewayOnline消息注册
func (cli *Client) registerGatewayOnlineHandler() {
	cli.handlers[command.BindRobotID] = cli.bindRobotIdHandler
	cli.handlers[command.HeartBeat] = cli.heartBeatHandler
}

// sendMsg 异步发送数据包
func (cli *Client) sendMsg(cmd uint16, msg interface{}) bool {
	return cli.AsyncSend(uint16(cmd), msg)
}

func (cli *Client) OnMessage(data []byte) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error("[server_client] panic ", err, "\n", string(debug.Stack()))
		}
	}()
	cli.doWithRecvData(data)
}

func (cli *Client) doWithRecvData(data []byte) {
	recvData := &common.MsgRecvData{}
	err := json.Unmarshal(data, recvData)
	if err != nil {
		return
	}
	handler, ok := cli.handlers[command.Command(recvData.Cmd)]
	if ok {
		handler(recvData.Data)
		return
	}
	worldMsg := &common.WorldMsgData{
		RobotId:  cli.robotID,
		RecvData: recvData,
	}
	WorldGetMe().msgChan <- worldMsg
}

func (cli *Client) OnClose() {
	if cli.robotID != 0 {
		//WorldGetMe().removeRobotChan <- cli.robotID
		clientManagerGetMe().removeClient(cli.ConnID)
		clientManagerGetMe().unbindUserID2Client(cli.robotID)
	}
	logger.Infof("[连接] 客户端连接断开 local:%v remote:%v robotID:%v connID:%v", cli.LocalAddr(),
		cli.RemoteAddr(), cli.robotID, cli.ConnID)
}

func (cli *Client) Marshal(msgID uint16, msg interface{}) ([]byte, error) {
	//return cli.router.Marshal(msgID, msg)
	return nil, nil
}

func (cli *Client) OnConnect() {
	clientManagerGetMe().addClient(cli.ConnID, cli)
	logger.Infof("[连接] 建立连接 local:%s remote:%s connID:%v", cli.LocalAddr(), cli.RemoteAddr(), cli.ConnID)
	cli.remoteAddr = cli.RemoteAddr().String()
}

// 用户通过验证
func (c *Client) onUserVerify(robotID uint64) {
	c.robotID = robotID
	clientManagerGetMe().bindUserID2Client(robotID, c)
}
